<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script type="module">
    import { request } from "../js/ajax.js";

    // Promise的静态方法 -> 构造函数Promise自己的方法

    // Promise.all()

    // Promise.all()方法用于将多个 Promise 实例，包装成一个新的 Promise 实例。
    // const p = Promise.all([p1, p2, p3]);

    // 上面代码中，Promise.all()方法接受一个数组作为参数，p1、p2、p3都是 Promise 实例，如果不是，就会先调用下面讲到的Promise.resolve方法，将参数转为 Promise 实例，再进一步处理。另外，Promise.all()方法的参数可以不是数组，但必须具有 Iterator 接口，且返回的每个成员都是 Promise 实例。

    // p的状态由p1、p2、p3决定，分成两种情况。

    // （1）只有p1、p2、p3的状态都变成fulfilled，p的状态才会变成fulfilled，此时p1、p2、p3的返回值组成一个数组，传递给p的回调函数。

    // （2）只要p1、p2、p3之中有一个被rejected，p的状态就变成rejected，此时第一个被reject的实例的返回值，会传递给p的回调函数。

    // 总结: 
    // 全都成功才成功,有一个失败就失败 
    //     T1
    // T = T2    => 全都成功按最慢的, 失败的话按最快的
    //     T3






    // 模拟封装Promise.all()

    Promise.myAll = function (list) {
        // var list = [p1, p2, p3];
        return new Promise(function (resolve, reject) {
            var arr = [];
            var count = 0;
            for (let i = 0; i < list.length; i++) {
                let p = list[i]; // 每一个Promise实例 (未来改变状态和存储结果 -> 异步)
                p = Promise.resolve(p);
                p.then(data => { // Promise实例状态改变之后(fulfilled) -> 执行的函数 (先变先执行)
                    console.log("fulfilled", data);
                    // arr.push(data);  // 先变的先放
                    // console.log(i);
                    arr[i] = data;
                    count++;
                    if (count == list.length) { //请求全都成功
                        // console.log(arr);  //此时数据只能在当前回调函数中使用 -> 无法传出去
                        resolve(arr);
                    }

                }).catch(err => {// Promise实例状态改变之后(rejected) -> 执行的函数
                    console.log("rejected", err);
                    reject(err);
                })
            }
        })
    }

    var p1 = getNumAsync(1, 2000);
    var p2 = getNumAsync(2, 1000);
    var p3 = getNumAsync(3, 3000);

    // var list = [p1, p2, p3];

    var p = Promise.all([p1, p2, p3, 4]);

    p.then(function (arr) {
        console.log("fulfilled", arr);
    }).catch(err => {
        console.log("rejected", err);
    })




    // 调用此方法 返回Promise对象(pending)  指定时间之后变为 fulfilled/rejected
    function getNumAsync(num = 0, delay = 0, isResolve = true) {
        return new Promise(function (resolve, reject) {
            setTimeout(function () {
                isResolve ? resolve(num) : reject(num);
            }, delay)
        })
    }

</script>

</html>